package com.poetize.plus.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author zuosy
 * @created 2024/3/28 15:36
 */
@Component
@RequiredArgsConstructor
public class RedisUtil {

    private final RedisTemplate<String, Object> redisTemplate;

    private final ObjectMapper objectMapper;

    /**
     * 门户系统统一缓存方法
     *      1：查看redis是否有缓存，有的话返回数据
     *      2：如果没有缓存，执行supplier查询数据库并将数据库数据set到redis后，再返回
     * @param key           缓存key
     * @param supplier      查询数据的方法
     * @return              返回查询数据的类型
     */
    public <T> T getHomeRedis(String key, Supplier<? extends T> supplier){
        Object redisObject = redisTemplate.opsForValue().get(key);
        return Optional.ofNullable(redisObject).map(obj -> {
            try {
                return objectMapper.readValue(redisObject.toString(), new TypeReference<T>() {
                });
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }).orElseGet(() -> setHomeRedis(key, supplier));
    }

    /**
     * 以key->key,value->supplier.get()形式存储到redis中
     * @param key           缓存key
     * @param supplier      查询数据库结果
     * @return              返回数据库查询结果
     * @param <T>           数据库查询结果返回类型
     */
    public <T> T setHomeRedis(String key, Supplier<? extends T> supplier){
        T t = supplier.get();
        try {
            String articleJson = objectMapper.writeValueAsString(t);
            redisTemplate.opsForValue().set(key, articleJson);
            return t;
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}
